<?php


namespace app\web\controller;


use app\api\controller\v2\Auth;
use app\common\cachemodel\MiniAppUser;
use app\common\cachemodel\ZlGoddessState;
use app\common\lib\exception\ApiException;
use app\common\lib\Jssdk;
use app\common\lib\Util;
use app\common\model\Recode as RecodeModel;
use app\common\model\User;
use think\Cache;
use think\Controller;
use think\Db;
use think\Env;
use think\Exception;
use think\Log;

class ActiveFortuneYear2021 extends Controller
{
    public const AVATAR_WIDTH = 76;//头像宽度
    public const AVATAR_HEIGHT = 76;//头像高度
    public const RANDOM_WORDS_INDEX_EXPIRED = 1296000;//关键字过期时间15天

    protected function _initialize(): void
    {
        parent::_initialize();
        $res = Util::androidVersion('2.2.0');
        $this->assign('version', $res);
    }

    protected $words = [
        '福气满满', '健康快乐', '考试顺利', '好运满满', '身体健康',
        '锦鲤附身', '好运无限', '诸事顺利', '开开心心', '顺风顺水',
        '准能暴富', '快乐不断', '准有好事', '事事称心', '准能脱单',
        '好运开挂', '准不水逆', '一切顺利', '准有好运', '充满动力',
        '准能上岸', '变瘦变美', '无忧无虑', '财源滚滚',
    ];

    protected $words_jupiter = [
        '你会变得更加聪明、自信、勇敢，敢于追求自己的目标和理想，无论做什么事情都目标明确且非常有行动力，也会因此收获许多好运。不过这段时间里，你们要注意暴饮暴食、发胖的问题。',
        '你的好运不体现在某个固定的世俗领域，你可能会感受不到好运的眷顾，内心很困扰，不过在你特别绝望的时候，会突然出现转机，有好运捞你一把。',
        '你的人缘会有所提升，无论是生活中还是网络上，你们都有可能加入某个组织、团体，认识到许多有着共同志向的朋友，并且受到大家的追捧和喜爱。',
        '是你事业上的高光时刻，会有很多幸运落到你身上，你也会积极主动地去争取每一个机会，并且做到最好。不过最好别太自我、独断，否则会影响合作关系的稳定。',
        '你在长途旅行、考研学业等方面的事情，会有一波好运。对于能够提升自己、开阔眼界的事情，充满了十足的热情。近期如果你有考试的话，会取得让你满意的成绩。',
        '你会更加关注自己的财富收入，会收到一些有关财富、金钱方面的好消息。另外，你也会比较注重合作关系的建立，涉及到感情的事情也能有一个好的开始。',
        '你在人际关系的领域会收获好运。面对感情的态度会变得乐观积极，同时，你身边会出现很多社交机会，能够帮助你拓宽视野，发现生活的乐趣和意义所在。',
        '你的身边会有更多机会出现，会被领导委以重任，开始接手一些重点项目，会有更多的人认可、支持你。同时，你对待工作的态度也会更加乐观，对未来充满期待。',
        '你的桃花运很不错，有机会脱单哦，可能会快速推进你的恋爱进度，拥有愉快的约会，当然也可能是和朋友去尽情玩乐，度过一段快乐的时光。',
        '你的家庭方面会有一些好消息，如果有计划搬家、装修，这期间可以行动起来，但是要注意过程中不要太过于求快，而忽略许多细节。',
        '你的学习、沟通方面会有一些好运。在学习上会更有动力，沟通上也会更加自信。这个时候也适宜计划短程旅行，但要注意仔细的规划一下才能有更好的体验哦。',
        '你的财务方面会有一些好运，你自己的价值也会得到充分的展现，这时候能够集中精力去挣钱，因此实现收入上的提升。注意不要冲动消费。'
    ];

    protected $words_mars = [
        '你的思维方式和说话方式都会变得比较直接，甚至是有些冲。建议你控制住情绪，再坚持一下，就会结束这段群星混战的时光。',
        '你要格外注意金钱上的问题，很可能会出现破财、漏财的情况。建议你在处理钱财的事情时要冷静、谨慎一些。',
        '你的行动力上会有些涣散，做事注意力不集中，这期间的性情也有些急躁，容易与身边人发生争执，沟通不太顺畅。',
        '你可能会因为工作的失意、繁忙或是学业上的迷茫，内心焦躁不安，精神状态不好，经常失眠、做噩梦。',
        '你会忙于一些交际、应酬的事情，需要与更多的人来往、打交道，因此容易遇到一些无理的人，甚至会因此发生摩擦和矛盾。',
        '你的事业心很强，想要做出成绩得到认可，但总会出现问题拖延你的进展，甚至会打断和你升职加薪有关的事情。',
        '你在学业、事业上可能没有什么动力，有点得过且过、三分钟热度的状态。同时，容忍度降低，很容易与周围人发生争吵、争执。',
        '你的财富领域，尤其是偏财容易受到影响，很容易产生情绪化消费，经济状况堪忧。建议你谨慎经营，保守行事，以免亏损严重。',
        '你在亲密关系的交往中会比较消极，缺乏活力，遇到矛盾时，会容易听从别人的建议，甚至是小道消息。建议你在感情中要给对方一些信任。',
        '你可能会想要换工作，或是在工作上会很忙碌，手忙脚乱，但是你也会很有动力，去改善工作方式，甚至是改生活、健康方式。',
        '你可能会遇到前任，或者发现自己陷入了一段三角恋情中，同时你对恋爱的热情会减弱，注意力经常跑到别的地方。',
        '你与家人的交流好像有点不对频，会出现闷火、冷战的情况。如果你有装修、租房的计划，可能会出现动力不足的情况。'
    ];

    public function index()
    {
        //微信分享
        $signPackage = '';
        //用户信息
        $userInfo = [
            'not_in_app_page' => 1,//页面里显示第几页
            'not_in_app_is_login' => 0,//不在App里的话，是否登录：0：没有登录；1：已登录；
            'isInApp' => 0,//0：不是在app里打开；1：是在app里打开；
            'type' => 0,//0：用户未登录；1：用户已登录；
            'app_type' => '',
            'uid' => '',
            'sign' => -1,
            'moon' => -1,
            'asc' => -1,
            'name' => '',
            'reg_year' => -1,
            'reg_month' => -1,
            'reg_day' => -1,
            'from_now_day' => -1,
            'count_record_2021' => -1,
            'count_synastry_2021' => -1,
            'max_score_synastry_2021' => -1,
            'word_jupiter' => '',
            'word_mars' => '',
        ];

        $headers = $this->request->header();

        if (isset($headers['sign']))
        {//在App里请求
            $userInfo['isInApp'] = 1;
            $userInfo['app_type'] = $headers['app-type'];
            //校验token
            try
            {
                $auth = new Auth();
                $auth->checkRequestAuth();
                $uid = $auth->user['id'];
                $userInfo = $this->getUserInfo($uid, $userInfo);
            }
            catch (\Exception $e)
            {
                Log::write('年度报告_在App里请求异常:' . $e->getMessage(), 'error', true);
            }
        } else
        {//在App外请求
            $token = session('active_fortune_year_2021.token');
            $userInfo['isInApp'] = 0;
            if ($token)
            {//开始解密，token是小程序h5生成的
                try
                {
                    // access-token AES解密
                    $accessUserToken = $this->decryptWithOpenssl($token);
                    if (empty($accessUserToken)) return false;
                    if (!preg_match('/||/', $accessUserToken)) return false;
                    [$token, $miniId] = explode('||', $accessUserToken);
                    $miniInfo = (new MiniAppUser())->getMiniAppInfo($miniId);
                    if (!$miniInfo || ($miniInfo['access_token'] !== $token) || $this->request->time() > $miniInfo['expires_in'] || (int)$miniInfo['status'] !== 0)
                    {   // 判断token是否过期 并且账户状态正常
                        throw new ApiException('登录失效', 200, config('code.denied'));
                    }

                    $uid = (int)($miniInfo['uid']);
                    $userInfo = $this->getUserInfo($uid, $userInfo);

                }
                catch (\Exception $e)
                {
                    Log::write('年度报告_在App外请求异常:' . $e->getMessage(), 'error', true);
                }
            }

            $ua = $_SERVER['HTTP_USER_AGENT'];
            if (strpos($ua, 'MicroMessenger') === false && strpos($ua, 'Windows Phone') === false)
            {
                //使用其他浏览器打开的
                $signPackage = '';
            } else
            {
                //微信登录
                $signPackage = (new Jssdk())->getSignPackage();
            }
        }


        $this->assign('data', [
            'not_in_app_login_url' => Env::get('host.wap_domain') . '/zhunle_wap_login?callback_url=' . urlencode(Env::get('host.domain') . '/web/active_fortune_year2021/callback_h5'),
            'not_in_app_is_login' => $userInfo['not_in_app_is_login'],//不在App里的话，是否登录：0：没有登录；1：已登录；
            'not_in_app_page' => $userInfo['not_in_app_page'],//页面里显示第几页

            'host' => $this->request->domain(),
            'ossHost' => Env::get('host.photo') . 'web',//本地测试
//            'ossHost' => Env::get('host.domain'),
            'title' => '和我一起回顾2021，签收你的2022年度运势盘点~',
            'share_title' => '和我一起回顾2021，签收你的2022年度运势盘点~', // 分享标题
            'share_introduction' => '听说看过的人在2022年都会获得好运加持哦！！', // 分享描述
            'signPackage' => $signPackage,
            'type' => $userInfo['type'],//0：用户未登录；1：用户已登录；
            'uid' => $userInfo['uid'],//用户id
            'sign' => $userInfo['sign'],//只有$type=1，并且有自己档案的时候，才显示自己的默认选中星座，否则默认为-1
            'moon' => $userInfo['moon'],//用户月亮星座
            'asc' => $userInfo['asc'],//用户上升星座
            'isInApp' => $userInfo['isInApp'],//0：不是在app里打开；1：是在app里打开；
            'app_type' => $userInfo['app_type'],//app 类型：android、ios
            'name' => $userInfo['name'],//用户昵称
            'reg_year' => $userInfo['reg_year'],//用户注册年
            'reg_month' => $userInfo['reg_month'],//用户注册月份
            'reg_day' => $userInfo['reg_day'],//用户注册日
            'from_now_day' => $userInfo['from_now_day'],//已注册了*天
            'count_record_2021' => $userInfo['count_record_2021'],//2021新增了多少档案
            'count_synastry_2021' => $userInfo['count_synastry_2021'],//2021合盘了多少次
            'max_score_synastry_2021' => $userInfo['max_score_synastry_2021'],//2021合盘的最高分数
            'word_jupiter' => $userInfo['word_jupiter'],//木星词条
            'word_mars' => $userInfo['word_mars'],//火星词条
        ]);

        return $this->fetch('index');
    }

    /**
     * 查询用户 档案、注册日期、新增档案、合盘数、合盘最高分 信息
     * @param string $uid
     * @return array
     * @throws \Exception
     */
    private function getUserInfo(string $uid = '', $userInfo = []): array
    {
//        $result = session('active_fortune_year_2021.user_info');
        try
        {
//            if (!$result)
//            {
            $result['uid'] = $uid;
            //查询用户档案
            $map = ['uid' => $uid, 'isself' => 1];
            $recode_info = (new RecodeModel())->getSelfRecode($map);
            if ($recode_info && isset($recode_info['sun']))
            {
                $sign = explode('-', $recode_info['sun'])[0];
                $result['sign'] = $sign;
                $result['moon'] = explode('-', $recode_info['moon'])[0];
                $result['asc'] = explode('-', $recode_info['asc'])[0];
                $result['not_in_app_page'] = 1;//设置请求第几页
                $result['not_in_app_is_login'] = 1;//登录成功
                $result['type'] = 1;
                $result['name'] = $recode_info['name'];
                $result['word_jupiter'] = $this->words_jupiter[$sign - 1];
                $result['word_mars'] = $this->words_mars[$sign - 1];
            }

            //查询用户注册日期
            $user_info = (new User())->field('reg_time')->where(['id' => $uid])->findOrFail();
            $user_info = json_decode(json_encode($user_info, true), true);
            if ($user_info && isset($user_info['reg_time']))
            {
                $reg_date = date('Y-m-d', $user_info['reg_time']);
                $reg_date_arr = explode('-', $reg_date);
                $result['reg_year'] = (int)$reg_date_arr[0];
                $result['reg_month'] = (int)$reg_date_arr[1];
                $result['reg_day'] = (int)$reg_date_arr[2];

                $result['from_now_day'] = round((time() - $user_info['reg_time']) / 3600 / 24);
            }

            //查询用户2021年新增了多少档案
            $result['count_record_2021'] = Db::table('app_recode')->alias('r')
                ->join('app_recode_info ri', 'r.id=ri.rid', 'INNER')
                ->field('r.id,ri.create_time')
                ->where(['r.uid' => $uid, 'r.status' => 1])
                ->whereBetween('ri.create_time', [1609430400, 1640966400])
                ->count();

            //查询用户2021年合盘了多少次
            $result['count_synastry_2021'] = Db::table('app_synastry_result')
                ->where(['uid' => $uid, 'status' => 1])
                ->whereBetween('create_time', [1609430400, 1640966400])
                ->count();

            //查询用户2021年合盘最高分
            $result['max_score_synastry_2021'] = Db::table('app_synastry_result')
                ->field('score')
                ->where(['uid' => $uid, 'status' => 1])
                ->whereBetween('create_time', [1609430400, 1640966400])
                ->max('score');

            session('active_fortune_year_2021.user_info', $result);
//            }
        }
        catch (Exception $e)
        {
            Log::write('年度报告2021_查询用户 档案、注册日期、新增档案、合盘数、合盘最高分 信息异常:' . $e->getMessage(), 'error', true);
        }

        return array_merge($userInfo, $result);
    }

    /**
     * h5登录返回
     */
    public function callback_h5(): void
    {
        $token = $this->request->param('token');
        session('active_fortune_year_2021.token', $token);
        $this->redirect('/web/active_fortune_year2021/index');
    }

    //开始生成用户头像保存到本地
    public function createAvatar(): \think\response\Json
    {
        $uid = htmlspecialchars(trim(input('get.uid/s')));
        $type = htmlspecialchars(trim(input('get.type/d')));

        $avatar_url = '';
        if (1 === (int)$type)
        {
            try
            {
                $user = (new User())->getUserinfo(['id' => $uid]);

                if (preg_match('/^http(s?):\/\/*/', $user['avatar']))
                {
                    $avatar_url = $user['avatar'];
                } else if (!empty($user['avatar']))
                {
                    $avatar_url = Env::get('host.photo') . $user['avatar'];
                }
            }
            catch (ApiException $e)
            {
            }
        }
        if (!empty($avatar_url))
        {
            $this->circleImg($avatar_url, $uid . '.png');
        }

        return show(config('code.success'), '请求成功', []);
    }


    /**
     * 获取报告内容
     * @return \think\response\Json
     * @throws ApiException
     * @throws \Exception
     */
    public function getReport(): \think\response\Json
    {
        $uid = htmlspecialchars(trim(input('get.uid/s')));
        //0：App未登录；1：App已登录；2：微信登录
        $type = htmlspecialchars(trim(input('get.type/d')));
        $name = '';
        switch ($type)
        {
            case 0:
                $name = '匿名用户';
                break;
            case 1:
                $user = (new User())->getUserinfo(['id' => $uid]);
                $name = $user['nickname'];
                break;
        }

        //获取缓存的indexs
        $cache_index = Cache::get('active_fortune_year_2021.index.' . $uid);

        if (!empty($cache_index))
        {//如果不为空
            $index = $cache_index;
            $index_word = $this->words[$index];
        } else
        {
            //四个字随机
            $index = random_int(0, count($this->words) - 1);
            $index_word = $this->words[$index];

            //存储用户的index，防止用户下次进来不一样
            Cache::set('active_fortune_year_2021.index.' . $uid, $index, self::RANDOM_WORDS_INDEX_EXPIRED);
        }

        return show(config('code.success'), '请求成功', [
            'name' => $name,
            'index' => $index,
            'index_word' => $index_word,
        ]);
    }

    /**
     * 生成报告图片
     */
    public function report(): void
    {
        $name = htmlspecialchars(trim(input('get.name/s', '匿名用户')));
        $uid = htmlspecialchars(trim(input('get.uid/s', '')));
        $index = htmlspecialchars(trim(input('get.index/s', '0')));
        $sign = htmlspecialchars(trim(input('get.sign/s', '1')));

        try
        {
            if ($index > count($this->words))
            {
                $index = 0;
            }
            header('Content-type: image/png');

            //画布
            $im = @imagecreatetruecolor(750, 1334) or die('Cannot initialize new GD image stream');
            //背景颜色
            $bg_color = imagecolorallocate($im, 72, 92, 176);
            imagefilledrectangle($im, 0, 0, 1500, 2668, $bg_color);// 创建画布
            //背景
            $img_bg = imagecreatefromstring(file_get_contents('./static/active_fortune_year_2021/img/p12/bg.png'));
            imagecopy($im, $img_bg, 0, 0, 0, 0, imagesx($img_bg), imagesy($img_bg));

            //微信 或者 app内用户 的头像
            $filePath = RUNTIME_PATH . 'active_fortune_year_2021' . DS . $uid . '.png';
            $avatar_left = 156;
            $avatar_top = 142;
            if (file_exists($filePath))
            {//文件存在
                $img_avatar = imagecreatefromstring(file_get_contents($filePath));
                imagecopy($im, $img_avatar, $avatar_left, $avatar_top, 0, 0, self::AVATAR_WIDTH, self::AVATAR_HEIGHT);
            } else
            {//文件不存在，使用默认的
                $img_avatar = imagecreatefromstring(file_get_contents('./static/active_fortune_year_2021/img/p12/avatar.png'));
                imagecopy($im, $img_avatar, $avatar_left, $avatar_top, 0, 0, self::AVATAR_WIDTH, self::AVATAR_HEIGHT);
            }

            //微信 或者 app内用户 的名字
            $name_left = 260;
            $name_top = 190;
            $name_color = imagecolorallocate($im, 255, 255, 255);
            imagettftext($im, 30, 0, $name_left, $name_top, $name_color, './static/active_fortune_year_2021/zk_font.ttf', $name);

            //随机词条 四个字
            $key_word = $this->words[$index];
            $left = 135;//左边距
            $key_word_color = imagecolorallocate($im, 255, 255, 255);//字颜色
            imagettftext($im, 90, 0, $left, 445, $key_word_color, './static/active_fortune_year_2021/zk_font.ttf', $key_word);

            //星座图片
            $img_sign = imagecreatefromstring(file_get_contents('./static/active_fortune_year_2021/img/p12/sign_' . $sign . '.png'));
            imagecopy($im, $img_sign, 358, 540, 0, 0, 400, 400);

            imagejpeg($im);
            imagedestroy($im);
            exit();
        }
        catch (\Exception $e)
        {
            throw new ApiException('[' . $e->getFile() . ':' . $e->getLine() . ']' . PHP_EOL . '：[name=' . $name . '&index=' . $index . '&uid=' . $uid . ']' . $e->getMessage());
        }

    }


    /**
     * 生成圆形图片
     * @param string $imgpath 图片地址/支持微信、QQ头像等没有后缀的网络图
     * @param $saveName string 保存文件名，默认空。
     * @return void 返回图片资源或保存文件
     */
    private function circleImg(string $imgpath, string $saveName = ''): void
    {
        //判断文件是否已经存在，如果存在那么返回，不存在那么生成
        $filePath = RUNTIME_PATH . 'active_fortune_year_2021' . DS . $saveName;
        if (file_exists($filePath))
        {
            return;
        }

        $src_img = imagecreatefromstring(file_get_contents($imgpath));
        $w = imagesx($src_img);
        $h = imagesy($src_img);
        $w = $h = min($w, $h);

        //缩放图片
        $des_w = self::AVATAR_WIDTH;
        $des_h = self::AVATAR_HEIGHT;
        //创建画布
        $zoom_img = imagecreatetruecolor($des_w, $des_h);
        //设置缩放起点
        $des_x = 0;
        $des_y = 0;
        $src_x = 0;
        $src_y = 0;
        imagecopyresampled($zoom_img, $src_img, $des_x, $des_y, $src_x, $src_y, $des_w, $des_h, $w, $h);
        //缩放图片

        $w = self::AVATAR_WIDTH;
        $h = self::AVATAR_HEIGHT;

        $img = imagecreatetruecolor($w, $h);
        //这一句一定要有
        imagesavealpha($img, true);
        //拾取一个完全透明的颜色,最后一个参数127为全透明
        $bg = imagecolorallocatealpha($img, 255, 255, 255, 127);
        imagefill($img, 0, 0, $bg);

        $r = $des_w / 2; //圆半径
        for ($x = 0; $x < $w; $x++)
        {
            for ($y = 0; $y < $h; $y++)
            {
                $rgbColor = imagecolorat($zoom_img, $x, $y);
                if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r)))
                {
                    imagesetpixel($img, $x, $y, $rgbColor);
                }
            }
        }

        //返回资源
        if (!$saveName)
        {
            return;
        }

        //输出图片到文件
        $settingDir = RUNTIME_PATH . 'active_fortune_year_2021';
        if (!is_dir($settingDir))
        {
            if (!mkdir($settingDir, 0755, true) && !is_dir($settingDir))
            {
                throw new \RuntimeException(sprintf('Directory "%s" was not created', $settingDir));
            }
        }
        $filePath = $settingDir . DS . $saveName;

        imagepng($img, $filePath);
        //释放空间
        imagedestroy($src_img);
        imagedestroy($img);
        imagedestroy($zoom_img);
    }


    /**
     * 解密字符串
     * @param string $data 字符串
     * @return string
     */
    protected function decryptWithOpenssl($data): string
    {
        $config = config('miniapp');
        return openssl_decrypt(base64_decode($data), $config['aes_method'], $config['aes_key'], OPENSSL_RAW_DATA, $config['aes_iv']);
    }
}
